﻿
using Dapper;
using hdal;
using hentity;
using hutil;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace hwms {
    /**
   *┌────────────────────────────────────────────────┐
   *│　描    述：Component                                                    
   *│　作    者：sgj                                              
   *│　版    本：1.0                                              
   *│　创建时间：2020/9/2 11:28:16                        
   *└────────────────────────────────────────────────┘
   **/
    public  class CoreUtil  
    {
      
        static public bool UpdataWhLoc(IDbConnection conn, IDbTransaction trans, long id,long goodDiff)
        {
            CoreWhLoc loc = conn.GetById<CoreWhLoc>(id, trans);
            if( loc != null ) {//非正常货位
                List<long> inOutList = getOutInCount(conn ,trans ,id);
                List<long> ining = inCount(conn ,trans ,id ,inOutList);
                List<long> outing = outCount(conn ,trans ,id ,inOutList);
                int remaindCount = getStore(conn ,trans ,id);
                int count = inOutList.Count + remaindCount + ining.Count + outing.Count;
                if( loc.Maxstock < count ) {
                    throw new Exception(String.Format("[{0}]货位存放货位过多[{1}][{2}][{3}]" ,id ,count ,ining ,outing));
                }
                if( count == 0 ) {
                    goodDiff = 0;
                }
                if( loc.countStock == count &&
                    loc.goodsDiff == goodDiff && 
                    loc.countIn == ining.Count && 
                    outing.Count == loc.countOut &&
                    inOutList.Count == loc.countOutin ) {
                    return true;
                }
                string sql2 = @"update core_wh_loc set Count_stock=@count,goods_diff=@goodDiff,Count_out=@outing ,count_in=@ining ,count_outin=@inOut  where id=@id";
                conn.Execute(sql2 ,new { id ,count ,goodDiff ,outing = outing.Count ,ining = ining.Count ,inOut = inOutList.Count } ,trans);
                updateMoveGroup(conn ,trans ,loc.areaId ,loc.moveGroup ,loc.craneId);
                saveCoreWhGroupStat(conn ,trans ,loc.areaId ,loc.moveGroup ,loc.goodsDiff);
            } else {
                CoreWhGroup group = conn.GetById<CoreWhGroup>(id ,trans);
                if( group != null ) {
                    updateMoveGroup(conn ,trans ,group.areaId ,group.locGroup ,0);
                    saveCoreWhGroupStat(conn ,trans ,group.areaId ,group.locGroup ,goodDiff);
                }
            }
            return true;
        }
        static List<long> getOutInCount(IDbConnection conn ,IDbTransaction trans ,long stn) {
            String outInCountSql = @" SELECT id FROM  Core_task where src=des  and status >= {0} and  status<{1} and src = @stn";
            outInCountSql = ToStr.formatInt(outInCountSql  ,CoreTaskStatus.新建,CoreTaskStatus.结束);
            List<long> outInCount = conn.Query<long>(outInCountSql ,new {  stn } ,trans).ToList();
            return outInCount;
         }

        static List<long> inCount(IDbConnection conn ,IDbTransaction trans ,long stn ,List<long> inOutList) {
            String inCountSql = @"SELECT task_Id FROM Core_task_param where des=@stn and status >= {0} and status <{1} and type = {2} " ;

          
            inCountSql = ToStr.formatInt(inCountSql ,CoreTaskParamStatus.新建 ,CoreTaskParamStatus.执行完成 ,TaskParamType.托盘搬运);
            List<long> inCount = conn.Query<long>(inCountSql ,new { stn } ,trans).AsList();

            foreach( long taskId in inOutList ) {
                inCount.Remove(taskId);
            }
            return inCount; 
        }

        static List<long> outCount(IDbConnection conn ,IDbTransaction trans ,long stn ,List<long> inOutList) {
            String outCountSql = @"SELECT task_Id FROM Core_task_param where src=@stn and status >= {0} and status <{1} and type = {2}";
            outCountSql= ToStr.formatInt(outCountSql ,CoreTaskParamStatus.新建 , CoreTaskParamStatus.执行完成 ,  TaskParamType.托盘搬运);


            List<long> outCount = conn.Query<long>(outCountSql ,new { stn  } ,trans).ToList();

            foreach( long taskId in inOutList ) {
                outCount.Remove(taskId);
            }
            return outCount;
        }


        static int getStore(IDbConnection conn ,IDbTransaction trans ,long stn) {//  库外 = 0,入库中 = 1,出库中 = 2,移库中 = 3,渡库中 = 4,出入库中 = 5,盘库中 = 6,库存 = 7,编辑 = 8,删除 = -1
            string sql = @"select count(*) from core_stock where  loc_Id=@locId and status ="+ (int)StockStatus.库存;//货出库中的货位，入库位置不在货位
            int remaindCount = conn.QueryUnique<int>(sql ,new { locId = stn } ,trans);
         
            return remaindCount;
        }

        static public   List<CoreWhLoc> getLoc4SelectIn(long areaId ,long moveGroup , IDbConnection Connection ,IDbTransaction transaction) {
             string sql = "select * from Core_Wh_Loc where  Active_Status in (0,2) and  wcs_Auto_active =1 ";
             if( areaId != -1 ) {
                 sql += " and   area_Id = @areaId  ";
            }
            if( moveGroup != -1 ) {
                 sql += " and   move_Group=@moveGroup  ";
            }
            sql += "order by order_No";
            List<CoreWhLoc> locList = Connection.Query<CoreWhLoc>(sql ,new { areaId ,moveGroup } ,transaction).ToList();
            return locList;
        }

        static public void saveCoreWhGroupStat(IDbConnection conn ,IDbTransaction tran ,long areaId ,int groupId ,long diffKey) {
            var param = new { areaId ,groupId ,diffKey };

            string sql = "select * from core_wh_group_stat where  group_Id =@groupId and  area_Id =@areaId and diff_Key=@diffKey ";

            CoreWhGroupStat diff = conn.QueryUnique<CoreWhGroupStat>(sql ,param ,tran);
            String countSql = "SELECT sum(Count_stock) FROM core_wh_loc  where move_Group = @groupId and area_Id = @areaId and goods_Diff = @diffKey";
            int cont = conn.QueryUnique<int>(countSql ,param ,tran);
            if( diff == null ) {
                diff = new CoreWhGroupStat();
                diff.id = WMSIdUtil.getId();
                diff.areaId = areaId;
                diff.groupId = groupId;
                diff.diffKey = diffKey;
                diff.countStock = cont;
                conn.InsertNoNull(diff ,tran);
            } else {
                string updateSql = "update core_wh_group_stat set count_stock=@countStock  where id=@id";
                diff.countStock = cont;
                conn.Execute(updateSql ,diff ,tran);
            }
        }


        static public  void updateMoveGroup(IDbConnection conn ,IDbTransaction tran ,long areaId ,int moveGroup ,int craneId) {
            CoreWhGroup group = getCoreWhGroup(conn ,tran ,areaId ,moveGroup);
            CoreWhGroup data = statAreaGroupData(conn ,tran ,areaId ,moveGroup);
            group.maxStock = data.maxStock;
            group.countStock = data.countStock;
            group.countIn = data.countIn;
            group.countOut = data.countOut;
            group.countOutin = data.countOutin;
            if( group.id == 0 ) {
                if( craneId > 0 ) {
                    group.id = getId(conn ,tran ,craneId);
                    group.craneId = craneId;
                    conn.Insert(group ,tran);
                }
    
            } else {
                String sql = @"  SELECT count(*) FROM core_task_param  where des = @des  and (type<>9 && status between 0  and 8)";
                group.countIning = conn.QueryUnique<int>(sql ,new { des = group.id } ,tran);
                conn.Update(group ,tran);
            }
        }

        static public  bool isAreaGroup(int id) {
            return id % 10000 >= 9000;
        }
        static public  int getId(IDbConnection conn ,IDbTransaction tran ,int craneId) {
            int id = craneId * 10000 + 9000;
            while( id / 10000 == craneId ) {
                CoreWhGroup group = conn.GetById<CoreWhGroup>(id ,tran);
                if( group == null ) {
                    return id;

                }
                id++;
            }
            throw new Exception(craneId+"库区太多");
        }

        static CoreWhGroup statAreaGroupData(IDbConnection conn ,IDbTransaction tran ,long areaId ,long moveGroup) {
            String sql = @" select sum(maxstock) maxStock,sum(count_stock) count_Stock,
                        sum(Count_out) count_out,sum(count_in) count_In,sum(count_outin) count_outin
                            from core_wh_loc 
                            where area_Id = @areaId and move_group=@moveGroup  and Active_Status in (0,1,2)";
            CoreWhGroup res = conn.QueryUnique<CoreWhGroup>(sql ,new { areaId ,moveGroup } ,tran);
            return res;
        }
        static CoreWhGroup getCoreWhGroup(IDbConnection conn ,IDbTransaction tran ,long areaId ,int moveGroup) {
            string sql1 = "select * from   Core_Wh_Group where area_Id=@areaId and loc_group=@moveGroup";
            CoreWhGroup group = conn.QueryUnique<CoreWhGroup>(sql1 ,new { areaId ,moveGroup } ,tran);
            if( group == null ) {
                group = new CoreWhGroup();
                group.areaId = areaId;
                group.locGroup = moveGroup;
            }
            return group;
        }

    }
}
